package com.jvm.classloader;

import com.jvm.classloader.custom.CustomClassLoader02;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;

/**
 * CustomLoaderDemo.. 自定义类加载器
 *
 * @author Lizhong
 * @date 2019/3/13
 */
public class CustomLoaderDemo extends ClassLoader {
    /**
     * classpath:为绝对路径
     */
    // private String classPath = "E:\\gihubSource\\TestDir\\java-all-test\\java-se\\target\\classes\\";
    private static String USER_DIR = System.getProperty("user.dir");
    private String classPath = USER_DIR + "\\java-se\\target\\classes\\";


    public CustomLoaderDemo() {
        super();
    }

    public CustomLoaderDemo(String classPath) {
        super();
        this.classPath = classPath;
    }

    /***
     *  双亲委派，当没有原文件时，只能通过findClass()方法
     */
    @Override
    protected Class<?> findClass(String name) {
        try {
            byte[] bytes = loadClassAsStream(name);
            Class<?> clazz = defineClass(name, bytes, 0, bytes.length);
            return clazz;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将java 文件编译成class，删除原文件，class文件放入classPath，将class文件以流的方式读入
     * @param name
     * @return
     * @throws IOException
     */
    private byte[] loadClassAsStream(String name) throws IOException {
        name = name.replaceAll("\\.", "/");
        InputStream inputStream = new FileInputStream(new File(classPath + name + ".class"));
        int available = inputStream.available();
        byte[] bytes = new byte[available];
        inputStream.read(bytes);
        return bytes;
    }

    public static void main(String[] args) throws Exception {
        CustomLoaderDemo customLoaderDemo = new CustomLoaderDemo();
        String name = "com.jvm.classloader.LoaderSample";
        // Class<?> aClass = customLoaderDemo.findClass(name);
        // Object o = aClass.getConstructors()[0].newInstance();


        // String str = USER_DIR + "\\java-se\\target\\classes\\com\\jvm\\classloader\\LoaderSample.class ";
        String str = "C:\\Users\\Administrator\\Desktop\\";
        File file = new File(str);
        URL url = file.toURL();
        CustomClassLoader02 customeClassLoader02 = new CustomClassLoader02(new URL[]{url});
        Class<?> aClass1 = customeClassLoader02.loadClass("LoaderSample");
        ClassLoader classLoader = aClass1.getClassLoader();
        System.out.println(classLoader);

        // LoaderSample loaderSample = new LoaderSample();
        // 加载任意位置class
        method01();
    }

    /**
     * 源文件类容
     *
     * package com.jvm.classloader;
     *
     * public class LoaderSample {
     *     public LoaderSample() {
     *         System.out.println(this.getClass().getClassLoader().getClass());
     *     }
     * }
     */
    public static void method01() throws IllegalAccessException, InvocationTargetException, InstantiationException {
        CustomLoaderDemo customLoaderDemo = new CustomLoaderDemo("C:\\Users\\Administrator\\Desktop\\");
        String name = "LoaderSample";
        Class<?> aClass = customLoaderDemo.findClass(name);
        Object o = aClass.getConstructors()[0].newInstance();
    }
}
